#!/bin/bash
 
#This Script utilizes curls ability to download files in parts
#
#Project:  http://code.google.com/p/splitcurl
#License:  http://directory.fsf.org/wiki/License:BSD_3Clause

function usage {
  echo -e "Usage:\n\t`basename $0` URL [SPLITNUM(4)]"
  exit 1
}
 
#Cleanup on kill
function clean {
  kill 0
  rm /tmp/$FILENAME.* 2> /dev/null
  echo "Download failed!"
  exit 1 
}
 
#Check parameters
if [ ! "$1" ];then
  echo "Where's the URL?"
  usage
fi
 
SPLITNUM=${2:-4}
URL=$1
FILENAME="`basename $URL`"
SIZE="`curl -qI $URL 2> /dev/null|awk '/Length/ {print $2}'|grep -o '[0-9]*'`"
SIZE=${SIZE:-1} 
[ $SIZE -gt 0 ] || SPLITNUM=1
START=0
CHUNK=$((${SIZE:-0}/$SPLITNUM))
END=$CHUNK
 
#Trap ctrl-c
trap 'clean' SIGINT SIGTERM
 
#Test splitness
OUT=`curl -m 2 --range 0-0 $URL 2> /dev/null|while read -n 1 C;do
  OUT="${OUT}½"
  echo $OUT
  [ ${#OUT} -gt 1 ] && break
done`
#Check out
case ${#OUT} in
0)  clean;; #Curl error
1)  ;; #Got a byte
*)  echo Server does not spit...;SPLITNUM=1;; #Got more than asked for
esac
 
#Invoke curls
for PART in `eval echo {1..$SPLITNUM}`;do
  curl --ftp-pasv -o /tmp/$FILENAME.$PART --range $START-$END $URL 2> /dev/null &
  START=$(($START+$CHUNK+1))
  END=$(($START+$CHUNK))
done
 
TIME=$((`date +%s`-1))
function calc {
 GOTSIZE=$((`eval ls -l /tmp/$FILENAME.{1..$SPLITNUM} 2> /dev/null|awk 'BEGIN{SUM=0}{SUM=SUM+$5}END{print SUM}'`))
 TIMEDIFF=$(( `date +%s` - $TIME ))
 RATE=$(( ($GOTSIZE / $TIMEDIFF)/1024 ))
 PCT=$(( ($GOTSIZE*100) / $SIZE ))
}
#Wait for all parts to complete while spewing progress
while jobs | grep -q Running;do
 calc
 echo -n "Downloading $FILENAME in $SPLITNUM parts: $GOTSIZE / $SIZE bytes @ $RATE kb/s ($PCT%).    "
 tput ech ${#SIZE}
 tput cub 1000
 sleep 1
done
calc
echo "Downloading $FILENAME in $SPLITNUM parts: $GOTSIZE / $SIZE bytes @ $RATE kb/s ($PCT%).    "
 
#Join all the parts
eval cat /tmp/$FILENAME.{1..$SPLITNUM} > $FILENAME
echo "Files done!"
rm /tmp/$FILENAME.* 2> /dev/null
